Florian Müllner [Wed, 4 Feb 2026 13:12:25 +0000 (14:12 +0100)]
swipeTracker: Handle invalid position when finding previous point
Commit 8e29babca8adc677 switched to `findLastIndex()` to find
the previous point, which inadvertently changed what value is
returned for invalid input.
Restore the old fallback value and log a stacktrace, so we can
hopefully track down what causes the invalid input.
Related: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/8856
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/4062>
(cherry picked from commit eb9caf0028be0d5740fc419e7e865584c0f52cab)
Sebastian Keller [Wed, 21 Jan 2026 21:54:39 +0000 (22:54 +0100)]
main: Only call gjs_dumpstack() on warnings from main thread
The mozjs code called by gjs_dumpstack() does not appear to be thread
safe and was sometimes resulting in crashes when triggered by error
messages from threads other than the main thread. And even when not
crashing, such a backtrace can only be misleading since only the main
thread is executing JS code.
This is not a good habit anywhere and especially in JS code, I assume
the rationale for this was to ensure that cached instances of the proxy
were cleared, but this did not work properly (as it happened on
finalize), and it would still require [1].
So let's just avoid this and assume that the getters just return what we
expect.
gdm/util: Clear the request if user verifier connection is closed
Similarly to previous commit, in case the user verifier connection is
closed we should just clear the user verifier instance, since starting
from this point is going to be just invalid.
gdm/loginDialog: Reset the greeter proxy on connection closed
If gdm fails to start the display session the greeter proxy we are using
gets disconnected, however since commit 56ea95f2 we are now preserving
the greeter instance, and this will eventually lead to using an instance
of a disconnected proxy.
This eventually implies that after a login failure, we would never get
the `::session-opened` signal that actually triggers the session start.
And thus, even the user has properly authenticated, gdm will stick to
the authentication page.
So, instead of reverting such commit (that isn't wrong per se), consume
the greeter proxy connection `::closed` signal and use it to
re-initialize the greeter instance.
gdm/util: Set minimum display time for authentication messages
Short messages like "PIN locked" were previously displayed for only
480ms (10 chars × 48ms), making them impossible to read. Ensure all
messages are shown for at least 2 seconds.
Ramez Medhat [Wed, 21 Jan 2026 15:28:22 +0000 (17:28 +0200)]
quickSettingsMenu: Add actor group to focus manager
This allows focus to menu item using the tab key to match the behaviour in other menus.
Closes https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/8904
Sebastian Keller [Sat, 24 Jan 2026 17:15:43 +0000 (18:15 +0100)]
appDisplay: Only create default folders on the first start
If all folders were removed, after a session restart the default folders
would have been recreated again, effectively preventing users from
using the app grid without folders.
Avoid this problem by only creating the default folders if the
folder-children setting has never been modified before.
Related: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/8713
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/4047>
(cherry picked from commit 889c1a444fcfd0588716528b8ee7dd858a610694)
Sebastian Keller [Wed, 21 Jan 2026 18:50:33 +0000 (19:50 +0100)]
st/spinner-content: Fix CoglTexture leak
Most of the members were getting indirectly freed via the
st_spinner_content_set_actor (spinner, NULL) and the subsequent
st_spinner_content_invalidate () on destruction of the actor or
changing of its content when the spinner is stopped.
The texture however was not freed.
This now frees all members explicitly on finalize.
208 (96 direct, 112 indirect) bytes in 1 blocks are definitely lost in loss record 20,960 of 22,464
at 0x4D37833: g_type_create_instance (gtype.c:1877)
by 0x4D1C186: g_object_new_internal.part.0 (gobject.c:2666)
by 0x4D1E0FA: g_object_new_internal (gobject.c:2982)
by 0x4D1E0FA: g_object_new_valist (gobject.c:3004)
by 0x4D1E488: g_object_new (gobject.c:2479)
by 0x5A8B7CB: _cogl_texture_2d_create_base (cogl-texture-2d.c:84)
by 0x572D668: st_spinner_content_paint_content (st-spinner-content.c:175)
by 0x50D2C07: clutter_actor_paint_node (clutter-actor.c:3471)
by 0x50D2C07: clutter_actor_continue_paint (clutter-actor.c:3726)
by 0x511D4F9: clutter_paint_node_paint (clutter-paint-node.c:867)
by 0x50D9717: clutter_actor_paint (clutter-actor.c:3670)
by 0x574199A: st_viewport_paint (st-viewport.c:483)
by 0x50D2C42: clutter_actor_continue_paint (clutter-actor.c:3728)
by 0x511D4F9: clutter_paint_node_paint (clutter-paint-node.c:867)
If we use a regular idle watch, any session inhibitors can prevent the
watch from triggering, leading to the break manager to never consider
the break as having been completed until the inhibitor is gone. This
could lead to situations in which the system appears to be stuck with
a dimmed screen.
Also start the idle time when the idle watch is created, otherwise any
previous idle time would count towards it, causing the watch to trigger
early, leaving it inconsistent with the rest of the break manager state.
Carlos Garnacho [Mon, 24 Nov 2025 16:16:57 +0000 (17:16 +0100)]
shellDBus: Add new BrightnessChanged signal to brightness interface
This does actually track user-triggered changes, so other pieces
(i.e. gsd-power) can react to this. This will help in reintroducing
brightness re-normalization when brightness is driven by ALS sensors.
revisto [Wed, 17 Dec 2025 21:13:47 +0000 (00:43 +0330)]
calendar: Center align "No Notifications" text
The "No Notifications" placeholder was left-aligned instead of
centered, which looked unbalanced in the empty notification state.
Fix by centering the label.
Closes: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/8913
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/4005>
(cherry picked from commit 8efd2ec8b9c62cac7e875bc8d7b596b2b1f90f7c)
Hari Rana [Sat, 13 Dec 2025 03:36:57 +0000 (22:36 -0500)]
overviewControls: Use ease-out-sine when entering overview and app grid
Using animations with slower initial curves on display-wide
layout shifts may provide a smoother experience to users of
low(er) refresh rate and/or large(r) displays, as they avoid
skipping large chunks of frames, making it less choppy at
the beginning of the animation.
screenShield: Fix user deselection after idle in greeter
When the session goes idle, _maybeCancelDialog() cancels any ongoing
authentication dialog. Commit b16ee1a added code to grab focus after
cancellation, ensuring it stayed on the lock screen curtain rather than
wherever cancel() placed it. This was needed to handle keyboard events
like Enter to raise the unlock dialog.
Commit 727c84251 changed this to grab focus on the dialog itself, since
the lock screen architecture had evolved. However, in the greeter case
there is no separate curtain - the LoginDialog is shown directly and
cancel() already restores focus to the user list via _showUserList().
The additional focus grab on the dialog container moved focus away from
the selected user as soon as the screen began to dim, causing the
username to appear deselected when returning from idle.
Similarly, _ensureUnlockDialog() and _resetLockScreen() grabbed focus on
the dialog container when the screen fully blanked, causing the same
issue.
For the greeter, replace grab_key_focus() with activate(), which
delegates to LoginDialog.activate() and properly focuses the user list.
For the unlock dialog, keep the original grab_key_focus() behavior -
calling UnlockDialog.activate() would invoke _showPrompt(), which would
interfere with commit 4bfa30085 that returns to the clock view after
suspend.
Florian Müllner [Tue, 9 Dec 2025 13:33:38 +0000 (14:33 +0100)]
swipeTracker: Handle touchpad gestures on actor
Touchscreen gestures and scrolling are already handled by events
on the associated actor rather than the stage. There's no good
reason to not do the same for touchpad gestures as well.
Closes: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/8850
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/3997>
(cherry picked from commit 006cef5a687814a5560a564811b16e76430291fc)
Florian Müllner [Fri, 5 Dec 2025 09:06:32 +0000 (10:06 +0100)]
workspaceAnimation: Use separate WorkspaceBackground class
Separating WorkspaceGroup and WorkspaceBackground allows each to
track its own set of windows without special-casing exceptions.
This will also give us more flexibility in the future, if we need
to reuse the background elsewhere. This may happen if we optionally
change the animation to a crossfade for the new `reduced-motion`
setting.
Florian Müllner [Fri, 5 Dec 2025 08:25:30 +0000 (09:25 +0100)]
workspaceAnimation: Split out BaseWorkspaceGroup
Since we started to show DESKTOP windows as part of the background
during the workspace animation, we need to track both the windows
relevant for the monitor/workspace and DESKTOP windows.
We are about to split out the background handling into its own class.
To prepare for this, split out a BaseWorkspaceGroup class that handles the
basic "create clones of relevant windows and track them" functionality
common to both cases.
environment: Ignore animation events after shutdown
As soon as the shutdown starts, any animation event does not make sense,
although during this phase the clutter timelines may still proceed and
potentially calling invalid code in their callbacks.
Prevent this from happening by disconnecting from any timeline signal
we are connected to as soon as the `shutdown` signal is emitted
environment: Generalize easeActorProperty to animatable case
We're not handling actors only with it but also St.Adjustment that is a
Clutter.Animatable, so let's name it for what it is, and adjust the
parameter so that its type is not given for granted
overviewControls: Wait for all animation promises on startup
Currently on startup we're just waiting for a single animation (the dash
one) being completed, while this is acceptable since the animation
duration is not shorter or longer than others, it's still not clean, as
technically we should just wait for all the pending animations of the
set before calling the startup animation completed.
Lukas Schmelting [Thu, 27 Nov 2025 22:58:32 +0000 (23:58 +0100)]
screenShield: Avoid unfocused authentication view after resume
When suspending on the authentication page of the lock screen in a user
session, the session resumes with the authentication dialog shown but
its password entry field unfocused. Instead, focus moves to the
authentication dialog itself while _ensureUnlockDialog() in
screenShield.js is called on resume.
Avoid this edge case by switching to the clock view instead before
suspend, which also provides a more consistent user experience.
messageTray: Disconnect to global signals on destruction
The global display object has always a longer lifetime than anything
that is initialized from JS, so avoid signals that it may emit to be
handled at later point.
It handles issues such as:
(gnome-shell:2429): Gjs-CRITICAL **: 23:18:35.025: Object
Gjs_ui_messageTray_MessageTray (0x3440ed60), has been already disposed —
impossible to set any property on it.
This might be caused by the object having been destroyed from C code using
something such as destroy(), dispose(), or remove() vfuncs.
== Stack trace for context 0x31073eb0 ==
#0 348db378 i resource:///org/gnome/shell/ui/messageTray.js:1046 (3a8ac3a71f60 @ 104)
#1 348db2d8 i resource:///org/gnome/shell/ui/main.js:277 (3a8ac3a0b100 @ 119)
Seen in: https://gitlab.gnome.org/GNOME/gnome-shell/-/jobs/5846454
Florian Müllner [Thu, 27 Nov 2025 14:41:44 +0000 (15:41 +0100)]
test-tool: Adjust name in --version
The tool was renamed from "perf-tool" a while ago, to reflect
that its purpose has shifted from collecting performance data
to running gnome-shell with scripted tests.
We are using it in overviewControls but the value is not exported.
This caused an issue when the animations are not enabled, since in a
racy way (e.g. only sometimes, depending on the init speed) the value
was undefined, and so we ended up falling back to the default animation
duration time.
In case an actor easing is created without an explicit duration, we
should rely to the default animation that Clutter.Actor.save_easing_state()
sets to 250ms.
This fine in normal use cases, but in case the animations are disabled
the current code skips calling our Clutter.Actor.set_easing_duration()
override, and so we just end up leaving the actor easing time to 250ms,
not respecting the St settings
The LongPressGesture 'may-recognize' callback in commit 314137c8c was
checking if clicks were inside '_switcherList', but thumbnails shown by
switch-group are siblings of _switcherList, not children.
This caused the gesture to incorrectly identify thumbnail clicks as
'outside' clicks, closing the popup before the click could complete.
Fix by adding a _isActorOutside() helper method that subclasses can
override to check additional containers. AppSwitcherPopup now properly
checks both _switcherList and _thumbnails.
Tested on Ubuntu 25.10 with GNOME Shell 49.0. Confirmed:
- switch-group mouse clicks now work
- switch-applications and switch-windows unaffected
- clicking outside the popup still closes it correctly
- no regressions introduced
Fixes: 314137c8c9 ("switcherPopup: Move to a ClutterGesture for closing the popup") Closes: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/8812
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/3959>
(cherry picked from commit 811364ae59340195aa1c9c3edcc0d784d39105c2)
Carlos Garnacho [Fri, 21 Nov 2025 13:46:03 +0000 (14:46 +0100)]
screenShield: Emit ::screen-lock-shown early with animated fades
If the screen is locked with animatedFade parameter enabled, the
screenShield currently defers the emission of this signal until the
lightbox toggles on. However the lightbox might be prevented from
ever doing that by later input.
If this emission is delayed enough, it will result in ShellDBus
missing the D-Bus timeout for replying to the Lock request, since
it does rely on this signal being emitted in order to reply back.
It does however make sense to keep setting the active state after
the animation, so the inhibitors are synchronized at the point the
lightbox kicks in.
Closes: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/8644
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/3971>
(cherry picked from commit 7f84efb1edd652e55441c48af14d19d7d6b15b4e)
Florian Müllner [Thu, 20 Nov 2025 15:09:44 +0000 (16:09 +0100)]
swipeTracker: Immediately flip delta in RTL locales
The delta is currently flipped in a shared code path, after appending
the unmodified value to the event history. As a result, the calculated
final velocity for touchpad gestures is wrong in RTL locales.
Fix this by modifying the delta immediately when handling the events,
so that all other code operates on the correct values.
Closes: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/8840
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/3967>
(cherry picked from commit a02835aacadbc14dc4350add3bae99c70e38f1b0)
Adrian Vovk [Thu, 1 May 2025 22:34:52 +0000 (18:34 -0400)]
main: Register session with GDM on startup
When no monitor is connected, gnome-shell starts but never emits
`startup-prepared` nor `startup-complete`. As a result, GDM never
detects that the shell has launched and plymouthd remains running,
preventing the system from reaching graphical.target.
Ensure that registerSessionWithGDM() is called even when no monitor
is connected, so GDM can terminate plymouthd and allow the system to
reach graphical.target properly.
Part of https://gitlab.gnome.org/GNOME/gdm/-/merge_requests/285
We are currently still using eslint 8.x which has been unsupported
for quite a while. Update the ci-run-eslint script to a verison
that uses the supported eslint 9.x.
There's no reason why this is not the case, given that these tests are
running in completely separated environments, so they are safe to run in
parallel
overviewControls: Disconnect signals on destruction
While we are not getting errors and the ControlsManger is normally always
alive, during destruction we could still get events from other objects
that are still alive, so disconnect them all
workspaceThumbnail: Track later hiding drop placeholder
When closing the shell during a relayout we are getting this error:
(gnome-shell:2559407): Gjs-CRITICAL **: 06:57:21.765: Object St.Bin,
has been already disposed — impossible to access it.
This might be caused by the object having been destroyed from C code
using something such as destroy(), dispose(), or remove() vfuncs.
== Stack trace for context 0x60991609b710 ==
#0 b resource:///org/gnome/shell/ui/workspaceThumbnail.js:1334 (5e050636fb0 @ 17)
#1 i resource:///org/gnome/shell/ui/main.js:279 (30c932d102e0 @ 119)
This is because the later we added is running even when not needed (e.g
when the placeholder is not visible already), but also because we may
run the later callback after the parent has been destroyed.
We (I) changed the test job to use a different path in commit 342d7ab34,
but the artifacts path was not adjusted :(
Fixes: 342d7ab34a ("ci: Start with a fresh build dir to ensure test dependencies are correct")
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/3945>
(cherry picked from commit 72b8c9044d9d8145014852ee2e7962396ff46ba2)
Sebastian Wick [Mon, 20 Oct 2025 11:38:37 +0000 (13:38 +0200)]
brightnessManager: Use slider as bias when auto brightness is being used
The code previously tried to ensure that the sliders were disabled when
auto brightness was active, and determine the brightness just from the
auto brightness target we get from g-s-d.
It turns out that users do want to still have some control over the
brightness, even if auto brightness is active.
The slider is now being used as a bias for the auto brightness target
instead.
This also means that we can drop the BrightnessScale::locked property.
Sebastian Wick [Thu, 30 Oct 2025 10:43:19 +0000 (11:43 +0100)]
brightnessManager: Propagate any attempted brightness change
The BrightnessScale was trying to be smart by not notifying changes of
its value when an action on it (stepUp, stepDown, cycleUp, set value)
resulted in no change.
It turns out that users do want to see an OSD even when their action
resulted in no change.
Always notify about attempted changes instead.
Closes: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/8770
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/3941>
(cherry picked from commit aaef85ecbd558fec8aa138678fe859de930d42dd)
Alessandro Bono [Thu, 30 Oct 2025 10:47:17 +0000 (11:47 +0100)]
loginManager: Use systemd session auto object to get session ID
Relying on the Display property is buggy when the gdm user spawns more than
one gnome-shell instance.
```
$ loginctl
SESSION UID USER SEAT LEADER CLASS TTY IDLE SINCE
11 42 gdm - 11778 manager-early - no -
c20 42 gdm seat0 34313 greeter tty1 yes 17h ago
c21 42 gdm - 34938 greeter - no -
c22 42 gdm - 35693 greeter - no -
```
From the logs:
```
$ journalctl -b | grep "Will monitor"
[...]
Oct 29 15:14:59 gnome-shell[34961]: Will monitor session c20
Oct 29 15:22:57 gnome-shell[35716]: Will monitor session c20
Oct 29 15:22:58 gnome-shell[35716]: Will monitor session c20
```
Use the systemd session auto object for getting the session id. We can't return
directly the session proxy created from it because it won't emit signals. From
the documentation[1]:
```
Signals are only emitted on objects referencing a specific session ID not on the
"/org/freedesktop/login1/session/self" or "/org/freedesktop/login1/session/auto"
convenience objects, as they can only be dereferenced relative to a method caller.
```
Sebastian Keller [Wed, 29 Oct 2025 10:09:02 +0000 (11:09 +0100)]
osk-layouts: Drop comma key from de-extended and at-extended layouts
The row containing that key was one key too long, which was causing
misalignment. The comma key is not shown in the us-extended layout
either and is available via long press on the dot key or via ?123,
making it the best candidate to remove from these layouts.
Closes: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/8756
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/3940>
(cherry picked from commit f076b775bbbe1f73307311c3c971ca8a12e67bf3)
The commit was causing freezes when changing layouts in some situations
and not all of these were adressed by f643915b, such as when switching
from the 3rd to the 4th layout using a xkb shortcut in the X11 session
with 4 layouts.
It was also breaking the order of switching layouts using modifier-only
xkb shortcuts to switch to the next group, which it caused to advance
multiple groups because of the shortcut being handled via both
_modifiersSwitcher() and _layoutGroupChanged().
Further it was possible for _layoutGroupChanged() to trigger an error
due to the locale layout added by _buildGroupStrings() at the end of the
xkb layout list being accessible via the xkb shortcuts. That layout was
not present in _inputSources, leading to "is" being undefined.
Florian Müllner [Tue, 21 Oct 2025 18:12:59 +0000 (20:12 +0200)]
tools: Symlink node_modules in project root
NPM assumes quite strongly that it manages the project as a
whole and its package/lock files are located in the project
root.
While we somehow managed to keep the npm tooling in a subfolder,
this comes at the cost of breaking imports of additional modules.
This will become relevant when we update eslint to a supported
version, as we want to keep using the `junit` formatter in CI,
which has now been split out into a separate module.
So bite the bullet and make the node_modules folder available in
the project root.
On the plus side, having the node_modules folder in the project
root allows language servers in IDEs/editors to pick it up.
Florian Müllner [Thu, 23 Oct 2025 12:06:08 +0000 (14:06 +0200)]
tools: Pin git node modules
Both changes in the config (like new/changes rules) and the eslint wrapper
(like updating to eslint 9.x) could require changes on the shell side, and
therefore require conscious update rather than randomly breaking the CI.
Sebastian Keller [Sat, 25 Oct 2025 11:03:55 +0000 (13:03 +0200)]
keyboard: Don't move window when it got unmanaged during shift animation
When a window with a text-entry at the bottom that had triggered the OSK
and was shifted up to avoid overlapping the OSK is closed right after
losing keyboard focus, this results in a crash. The focus loss triggers
the animation to move the window actor back into its original position,
which moves the underlying window when finished. That however will fail
when the window has been unmanaged and some of the underlying resources
have already been destroyed while the animation was playing.
Closes: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/8752
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/3933>
(cherry picked from commit 4900aad2deab7398e69b1a57a38285fa73974c0f)
Florian Müllner [Tue, 21 Oct 2025 22:57:26 +0000 (00:57 +0200)]
systemActions: Don't log error when cancelled
If the logout/reboot/shutdown actions are available, we expect them
to succeed. Unfortunately that changed in the light of systemd
inhibitors (that we don't know about in the shell, and that prevent
those actions now).
While it would be good to fix the underlying issue, we can at least
improve the error reporting in that case and not log the error when
the operation was cancelled: We don't know the underlying reason,
unlike gnome-session which should have logged a more helpful message.
Closes: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/8749
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/3927>
(cherry picked from commit d3f3f4e80d338133a2083dd5c267ed456b86303d)